#include "b_spline3.h"
#include <iostream>

const float BSpline3::b_spline_matrix[4][4] = {	{-1.0f/6.0f,3.0f/6.0f,-3.0f/6.0f,1.0f/6.0f},
												{3.0f/6.0f,-6.0f/6.0f,3.0f/6.0f,0.0f},
												{-3.0f/6.0f,0.0f,3.0f/6.0f,0.0f},
												{1.0f/6.0f,4.0f/6.0f,1.0f/6.0f,0.0f} };

BSpline3::BSpline3(){
	memcpy(this->matrix,BSpline3::b_spline_matrix,16*sizeof(float));
}

BSpline3::~BSpline3(){}

void BSpline3::calculatePoints(){
	buffer.clear();

	int limit = ((int)this->control.size())-4+1;
	for(int g=0;g<limit;g++){
		for(unsigned int u=0;u<BSpline3::step;u++){
			buffer.push_back(calculatePoint((float)u/(float)BSpline3::step,(float*)&(this->control)[g],stride));
		}
		//Para que en el ultimo caso pase por el u=Step
		if (g==limit-1)
			buffer.push_back(calculatePoint((float)BSpline3::step/(float)BSpline3::step,(float*)&(this->control)[g],stride));
	}
}

void BSpline3::closeBSpline(){
	// Imposible cerrar una Bspline cubica con menos 4 puntos
	if(this->controlSize()<4)
		return;

	float newX1 = -(control[1].x1-control.front().x1)+control.front().x1;
	float newX2 = -(control[1].x2-control.front().x2)+control.front().x2;
	float newX3 = -(control[1].x3-control.front().x3)+control.front().x3;

	control.push_back(Point(newX1,newX2,newX3));
	control.push_back(control[0]);
	control.push_back(control[1]);
	control.push_back(control[2]);

	calculatePoints();

	control.pop_back();
	control.pop_back();
	control.pop_back();
	control.pop_back();
}
